/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Map;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

/**
 *
 * @author insane
 */
public class Fov {

    private int[][] seecolor;
    private char[][] seemap;
    private int viewSizeHeight;
    private int viewSizeWidth;
    private int fov;
    private int startx;
    private int starty;
    private boolean[][] visible;
    private boolean[][] seeFovColor;

    private Fov() {
    }

    public Fov(char[][] seemap, int[][] seecolor, boolean[][] visible, int width, int height, int x, int y) throws FileNotFoundException, IOException, ClassNotFoundException {
        this.seemap = seemap;
        this.seecolor = seecolor;
        this.visible = visible;
        this.viewSizeHeight = height;
        this.viewSizeWidth = width;
        this.startx = x;
        this.starty = y;
        this.fov = MapConfig.getInstance().getFov();
        this.seeFovColor = new boolean[fov * 4 + 1][fov * 2 + 1];
    }

    public ArrayList checkSee() throws FileNotFoundException, IOException, ClassNotFoundException {
        checkFront(startx, starty);
        wallVisible(startx, starty);
        ArrayList results = new ArrayList();
        //results.add(seemap);
        results.add(seecolor);
        results.add(visible);
        results.add(seeFovColor);
        return results;
    }

    public boolean[][] wallVisible(int startx, int starty) throws FileNotFoundException, IOException, ClassNotFoundException {
        for (int w = startx - fov * 2; w <= startx + (fov) * 2; w++) {
            for (int h = starty - fov; h <= starty + fov; h++) {
                if (w < viewSizeWidth && h < viewSizeHeight && w > 0 && h > 0) {
                    if (MapUtils.checkMove(seemap, w, h)) {
                        visible[w][h] = true;
                        seecolor[w][h] = 2;
                    }
                }
            }
        }
        return visible;
    }

    public boolean checkDot(int x, int y) throws FileNotFoundException, IOException, ClassNotFoundException {
        if (MapUtils.checkMove(seemap, x, y)) {
            visible[x][y] = true;
            return false;
        }
        visible[x][y] = true;
        seecolor[x][y] = 2;
        checkFovColor(x, y);
        checkLine(x, y);
        return true;
    }

    public boolean checkFov(int x, int y) {
        for (int w = startx - fov * 2; w <= startx + (fov) * 2; w++) {
            for (int h = starty - fov; h <= starty + fov; h++) {
                if (x == w && y == h) {
                    return true;
                }
            }
        }
        return false;
    }

    public void checkFovColor(int x, int y) {

        int xx = x - startx + fov * 2;
        int yy = y - starty + fov;

        seeFovColor[xx][yy] = true;
    }

    public boolean checkDotLine(int x, int y) throws FileNotFoundException, IOException, ClassNotFoundException {
        if (x < 0 || y < 0 || x >= viewSizeWidth * 2 || y >= viewSizeHeight * 2) {
            return false;
        }
        if (MapUtils.checkMove(seemap, x, y)) {
            if (x >= this.startx - MapConfig.getInstance().getFov() * 2
                    && x <= this.startx + MapConfig.getInstance().getFov() * 2
                    && y >= this.starty - MapConfig.getInstance().getFov()
                    && y <= this.starty + MapConfig.getInstance().getFov()) {
                visible[x][y] = true;
            }
            return false;
        }
        if (checkFov(x, y)) {
            visible[x][y] = true;
            seecolor[x][y] = 2;
            checkFovColor(x, y);
        }
        return true;
    }

    public void checkFront(int startx, int starty) throws FileNotFoundException, IOException, ClassNotFoundException {
        //left
        for (int hl = startx; hl >= startx - this.fov * 2; hl--) {

            if (!checkDot(hl, starty)) {
                break;
            }
        }
        //right
        for (int hr = startx; hr <= startx + this.fov * 2; hr++) {
            if (!checkDot(hr, starty)) {
                break;
            }
        }
        //top
        for (int vt = starty; vt >= starty - this.fov; vt--) {
            if (!checkDot(startx, vt)) {
                break;
            }
        }
        //bottom
        for (int vb = starty; vb <= starty + this.fov; vb++) {
            if (!checkDot(startx, vb)) {
                break;
            }
        }
        //right top
        for (int d = starty, x = 0; x <= this.fov; x++, d--) {
            if (!checkDot(startx + x, d)) {
                break;
            }
        }
        //left top
        for (int d = starty, x = 0; x <= this.fov; x++, d--) {
            if (!checkDot(startx - x, d)) {
                break;
            }
        }
        //left bottom
        for (int d = startx, y = 0; y <= this.fov; y++, d--) {
            if (!checkDot(d, starty + y)) {
                break;
            }
        }
        //right bottom
        for (int d = startx, y = 0; y <= this.fov; y++, d++) {
            if (!checkDot(d, starty + y)) {
                break;
            }
        }

    }

    public void checkLine(int startx, int starty) throws FileNotFoundException, IOException, ClassNotFoundException {

        //left
        for (int hl = startx; hl > startx - fov; hl--) {
            if (!checkDotLine(hl, starty)) {
                break;
            }
        }
        //right
        for (int hr = startx; hr < startx + fov; hr++) {
            if (!checkDotLine(hr, starty)) {
                break;
            }
        }
        //top
        for (int vt = starty; vt > starty - fov; vt--) {
            if (!checkDotLine(startx, vt)) {
                break;
            }
        }
        //bottom
        for (int vb = starty; vb < starty + fov; vb++) {
            if (!checkDotLine(startx, vb)) {
                break;
            }
        }/*
        //right top
        for (int d = starty, x = 0; x < fov; x++, d--) {
        if (!checkDotLine(startx + x, d)) {
        break;
        }
        }
        //left top
        for (int d = starty, x = 0; x < fov; x++, d--) {
        if (!checkDotLine(startx - x, d)) {
        break;
        }
        }
        //left bottom
        for (int d = startx, y = 0; y < fov; y++, d--) {
        if (!checkDotLine(d, starty + y)) {
        break;
        }
        }
        //right bottom
        for (int d = startx, y = 0; y < fov; y++, d++) {
        if (!checkDotLine(d, starty + y)) {
        break;
        }
        }*/

    }
}
